/************************************************************************
                          trace.c
Function to display gel image.
Written by IL
Edited by CAS and Ken McDonald (GSC)

gelhigh is an index into arr(acedata, i, CLONE)
 it is equal clhigh->next if a contig exists.
gelclone[GELMAX] holds indices into arr(acedata, i, CLONE)
gelcloneindex[GELMAX] holds which gel for a clone
*************************************************************************/

#include <stdio.h>
#include "clam.h"
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <gtk/gtkwidget.h>
/* sness */
#include "gex.h"
#include "dirent.h"
#ifdef ALPHA
#include "sex.h"
#endif
#define SEEK_SET 0

#define GSCgel(name) (name[0]=='m' || name[0]=='n')
static char GSC_gels[1024] = "/nfs/GSC/Humanmap_agarose/fpc/Gel";

extern int FpGelCBpicked;
extern GtkWidget *ctg_window;
extern int Zbcm();

int filCheck();
void gelhighlight(), gelredraw(void), recalculorder();
void cloneHigh(), redrawfingerprints();

static int ClipHeight=3300;
static float GelAvg=6.0;
static float GeltoBand=13.0;
static float GelUnit= 78.0;  /* GelAvg * GeltoBand */

/* sness sep21/2000 */
static BOOL geltrail = 0;
static void toggletrail();
static void cleartrail();
static int geltrailbox;

static BOOL isthecloneinthisgel();
static void calcpixels(), movegel(), gelorderandmove(), gelremoveall();
static void bandpickQuit(), bandpick(), setgelzoom();
static void clipGel(), setclipmin(), setclipmax();
static void trailgel();

static int UseBandFiles=0;
static int *CloneBands[GELMAX];
static float gelsizepercol;
static float gelheight;
static float YY=10.0;     /* where the clones start */

static unsigned char *gelpixelptr,*calcpixelptr[GELMAX];
static int  var_blksz[GELMAX], gelnamebox[GELMAX], gelclonebox[GELMAX];
static int numposs, blksz, gelpixelsheight=800,gelpixelswidth=16;

static int clipbox, clipminbox, clipmaxbox;
static char chclipmin[5], chclipmax[5];
static int gelmovebox, geldeletebox, gelbandbox, gelavgbox, greenbox;
static BOOL geldelete=FALSE, gelmove=FALSE, gelband=FALSE, greenflag=FALSE;
static char chgelavg[5];

static void regen();
/****************************************************
              DEF: Clip
****************************************************/
static void clipGel()
{
  sscanf(chclipmin,"%d",&Proj.MinClip);
  sscanf(chclipmax,"%d",&Proj.MaxClip);
  sscanf(chgelavg,"%f",&GelAvg);
  regen();
}
static void  setclipmin(char *x)
{
  sscanf(x,"%d",&Proj.MinClip);
}
static void  setclipmax(char *x)
{
  sscanf(x,"%d",&Proj.MaxClip);
}
/*******************************************************
              Def: Zoom
********************************************************/

static void regen()
{
int i, c;
int savepick;

  savepick = gelhigh;
  gelhigh=-1;
  GelUnit = GeltoBand*GelAvg;
  if (Proj.MinClip > Proj.MaxClip) Proj.MinClip = Proj.MaxClip - 100;
  if (Proj.MinClip < 0) Proj.MinClip = 0;
  ClipHeight = Proj.MaxClip - Proj.MinClip + 1;
 
  c = gelcount;
  gelcount=0;
  for(i=0;i<c; i++){
    if (calcpixelptr[i]!=NULL) {
       /*free(calcpixelptr[i]);  crashes graphDestroy on sun*/
       calcpixelptr[i]=NULL;
    }
    if (CloneBands[i]!=NULL) {
       free(CloneBands[i]);
       CloneBands[i]=NULL;
    }
    addgel(gelclone[i], gelcloneindex[i]);
  }
  gelhigh = savepick;
  gelredraw();
}
static void startregen()
{
  sscanf(chclipmin,"%d",&Proj.MinClip);
  sscanf(chclipmax,"%d",&Proj.MaxClip);
  regen();
}

static void setgelzoom(char *temp)
{
int x;
  sscanf(temp,"%d",&x);
  if (x > 8) x=8;
  else if (x < 1) x=1;
  GelAvg = (float) x;
  startregen();
}
static void ZoomWhole()
{
  GelAvg = 6.0;
  startregen();
}
static void ZoomIn()
{
  if (GelAvg<8) {
    GelAvg += 1.0;
    startregen();
  }
}
static void ZoomOut()
{
  if (GelAvg>1) {
    GelAvg -= 1.0;
    startregen();
  }
}
/*******************************************************
               DEF: readGSCgels
********************************************************/
static int readGSCgels(int aceindex, int fpindex, char *gelnum)
{
  int i, j, k, x;
  CLONE *clone;
  BOOL found=0;
  DIR *dfd;
  struct dirent *dp2;
  char tmp[6], GSCname[CLONE_SZ];

  /*if (!GSCgel(gelnum)) return 0; 5dec99*/
  if( (dfd = opendir(GSC_gels)) == NULL) {
#ifdef SANGER
       printf("No GSC Gel directroy found %s\n",GSC_gels);
#endif
       return 0;
  }
  clone = arrp(acedata,aceindex,CLONE);
       /* convert SC to GSC */
  if (clone->clone[0]!='N') {
     GSCname[0]='N';
         /* skip bA, add 0's to make 4 digits */
     for (j=0, i=2; i<6 && isdigit((int)clone->clone[i]); i++) 
          tmp[j++] = clone->clone[i];
     for (k=1; k<5-j; k++) GSCname[k] = '0';
     for (x=0; x<j; x++) GSCname[k++] = tmp[x];

     GSCname[k++] = clone->clone[i++]; 
         /* add 0's to make 2 digits */
     for (j=0; j<2 && isdigit((int)clone->clone[i]); i++) 
          tmp[j++] = clone->clone[i];
     if (j==1) GSCname[k++] = '0';
     for (x=0; x<j; x++) GSCname[k++] = tmp[x];
     GSCname[k] = '\0';
  }
  else strcpy(GSCname, clone->clone);

  while( ((dp2 = readdir(dfd)) != NULL) && !found) {
       if(strcmp(dp2->d_name,".") == 0 || strcmp(dp2->d_name,"..") == 0)
           continue;
       if(strstr(dp2->d_name,gelnum))
          found = isthecloneinthisgel(aceindex, fpindex, GSCname, GSC_gels,dp2->d_name);
  }
  closedir(dfd);
  if (!found) printf("Cannot find %s  --> %s \n", clone->clone, GSCname);
  return found;
}
/*************************************************************
               DEF: Getbands
**************************************************************/
static int GetBands(CLONE *clp, int kk, struct fpdata *p) 
{
FILE *bandsFilePtr; 
char bandsFileName3[1024];
char fp[CLONE_SZ], name[CLONE_SZ]; 
char line[100]; 
int  temp; 
int nbands;

    if (p->b2==0) return 0;
    if (strlen(dirName) > 0) 
        sprintf(bandsFileName3, "%s/Bands/%s.bands", dirName, p->gelname);
    else  sprintf(bandsFileName3, "Bands/%s.bands",  p->gelname);

    if ((bandsFilePtr = fopen(bandsFileName3, "r"))==NULL) {
       printf("No bands file %s\n", bandsFileName3);
       return 0;
    }
    if (p->fpchar[0]==' ') strcpy(fp,"!~&");
    else strcpy(fp, p->fpchar);

    if ((CloneBands[kk] = (int *) malloc((p->b2+1) * sizeof(int)))==NULL) {
        printf("Error: cannot allocate memory for bands.\n");
        return 0;
    }
    CloneBands[kk][0] = -1;

    while (1) {
      if (!fgets(line, 80, bandsFilePtr)) break;
      sscanf(line, "%s", name);
      if (strcmp(name, clp->clone)!=0 &&
          strcmp(name, fp)!=0) continue;

      fscanf(bandsFilePtr, "%i", &temp);
      nbands=0;
      while (temp != -1) {
          CloneBands[kk][nbands++] = temp;
          fscanf(bandsFilePtr, "%i", &temp);
      }
      CloneBands[kk][nbands] = -1;
      return 1;
   }
   if (p->fpchar[0]==' ')
        printf("No clone %s in %s\n", clp->clone, bandsFileName3);
   else
        printf("No clone %s or fp_name %s file %s\n", 
                  clp->clone, p->fpchar, bandsFileName3);
   return 1;
}
/*********************************************************
               DEF: do_gelhigh
**********************************************************/
void do_gelhigh()
{
  gelredraw();
}
/*********************************************************
               DEF: gelhighlight
**********************************************************/
void gelhighlight()
{
  static int last=-1;
  int kk;
  int newposs=-1,numposs=0,nx,ny;

  if(!graphActivate(gtest)) return;
  if(gelhigh == -1) return;

  for(kk=0;kk<gelcount;kk++){
      if(gelclone[kk] == gelhigh){
	newposs = kk;
	break;
      }
  }
  if(newposs != -1){
      graphFitBounds(&nx,&ny);
      numposs = (int)(nx/5);
      if(newposs < gelcolstart || newposs >= (gelcolstart+numposs)) {
         last = newposs;
         gelcolstart = newposs -(numposs/2);
      }
  }
  gelredraw();
}
/************************************************************
             DEF: gelclonehigh()
called from gelpick when a clone on the gel is picked
************************************************************/
void gelclonehigh(int box)
{
  int i;
  int gel = -1;
  struct contig *p;

  if (geladd) return;
  for(i=0;i<gelcount;i++){
    if(gelclonebox[i] == box || gelnamebox[i] == box){
      gel = i;
      break;
    }
  }
  if (gel==-1) return; /* shouldn't happen */
  
  if(gelhigh == gelclone[gel]) {
     displayclone(gelhigh);
     return;
  }
  gelhigh = gelclone[gel];
  do_gelhigh();
  /* cari 17.5.4 */
  if(ctg_window!=NULL){
    if (arrp(acedata,cloneindex[i],CLONE)->ctg == currentctg ||
       (merging && arrp(acedata,cloneindex[i],CLONE)->ctg == mergecontig2))
    {
          for(p=root; p != NULL; p = p->new){
              if(p->next == gelhigh){
                 FpGelCBpicked=2;
                 cloneHigh(p);
                 break;
              }
          } 
     }
  }
  /*else { cari 7-5-4 */
  for(fphigh = -1, i=0;i<FPMAX && cloneindex[i]!=-1;i++){
         if(cloneindex[i] == gelhigh){
	   fphigh =i;
           redrawfingerprints();
	   break;
         }
   }
}
/*************************************************************
                   gelprinthigh
add all selected clones
*************************************************************/
void gelprinthigh()
{
  struct contig *p;
  CLONE *clone;
  int savehigh=-1;

  if(ctg_window==NULL)
    return;
  if (fpRead() == -1) return;

  for (p=root; p!=NULL; p = p->new) {
      clone = arrp(acedata,p->next,CLONE);
      if(!clone->selected) continue;
         /* cari 4 feb 05 */
      if (showburied==1 && clone->match[0]!=' ') continue;

      if (gelhigh==p->next) {
          savehigh=gelhigh;
          gelhigh=-1;
      }
      addgel(p->next,0);
  }
  gelhigh=savehigh;
  gelredraw();
  graphPop();
}
/*******************************************
          DEF: gelPrint2
called from a clone text box when a gel is selected (on Gel pull-down)
*******************************************/
void gelPrint2(int box)
{
  CLONE *clone;

  if(clonedisplayed < 0 || clonedisplayed >= arrayMax(acedata)){
    printf("ERROR: index is out of range\n");
    return;
  }
  clone = arrp(acedata,clonedisplayed,CLONE);

  if(clone->ctg == 0) box = box - 1;
  else box = box - 2;

  addgel(clonedisplayed,box);
  gelredraw();
  graphPop();
}
/******************************************************
              DEF: gelPrint
called from a contig display when the Gel Image is selected on the
pull-down for a clone
**********************************************************/
void gelPrint(int box)
{
  struct contig *p;
  BOOL last,found;

  p = root; 
  last = found = FALSE;

  while(!last){   
    if(p->box == box || p->chbox == box){  
      box = p->box;
      found = TRUE;
      break;
    }
    if(p->new==NULL)
      last = TRUE;
    p = p->new;
  } 
  if(!found){
    printf("ERROR could not find clone for box???\n");
    return;
  }
  addgel(p->next,0);
  gelredraw();
  graphPop();
}
/***************************************************************
                DEF: gelquit
****************************************************************/
void gelquit()
{
int i;
  if(graphActivate(gtest))
    graphDestroy(); /* frees calcpixelptr */
  geladd =gelmove = geldelete= geltrail =FALSE;
  for(i=0;i<gelcount; i++){
    gelclone[i] = 0;
    gel_trail[i] = 0;
    if (calcpixelptr[i]!=NULL) {
       /*free(calcpixelptr[i]);*/
       calcpixelptr[i]=NULL;
    }
    if (CloneBands[i]!=NULL) {
       free(CloneBands[i]);
       CloneBands[i]=NULL;
    }
    bandpickQuit();
  }
  gelcount = 0;
  gelhigh = -1;
  geldelete=gelmove=gelband=geladd= geltrail=FALSE;
}

/*******************************************************************
                  DEF: addgel
cari 10.5.4 changed from int addgel to void addgel 
as all routines were calling it as void
******************************************************************/
void addgel(int aceindex,int fpindex)
{
  int i;
  CLONE *clone;
  BOOL found=0;
  struct fpdata *p;
  char gelfile[DIR_BUFFER_SIZE];
  DIR *dfd;
  struct dirent *dp2;
  char gelnum[GEL_SZ];

  if(fpRead()<0) return;
  ClipHeight = (Proj.MaxClip - Proj.MinClip) + 1;
    
  clone = arrp(acedata,aceindex,CLONE);
  if(gelcount >= (GELMAX-1)){
    printf("Only %d gels can be displayed at the same time -- ignoring %s\n",
          GELMAX, clone->clone);
    return;
  }
  if(clone->fp== NULL) {
       printf("No fingerprint for clone %s\n",clone->clone);
       return;
  }
  p= clone->fp;
  for (i=0;i<fpindex;i++)
      p = p->next;
  if(p==NULL){
      printf("ERROR  Clone %s with index of %d not found",clone->clone,fpindex);
      return;
  }
  if(strlen(dirName) > 0)
      sprintf(gelfile,"%s/Gel",dirName);
  else
      strcpy(gelfile,"./Gel");
  sprintf(gelnum,"%s",p->gelname);

          /* search through /Gel directory */
  if( (dfd = opendir(gelfile)) == NULL) goto GSC_search;
  
  while( ((dp2 = readdir(dfd)) != NULL) && !found) {
      if(strcmp(dp2->d_name,".") == 0 || strcmp(dp2->d_name,"..") == 0)
          continue;
      if(strstr(dp2->d_name,gelnum))
	found = isthecloneinthisgel(aceindex,fpindex, p->fpchar, gelfile,dp2->d_name);
  }
  closedir(dfd);
  if(found) return;

GSC_search: ;
  found = readGSCgels(aceindex, fpindex, gelnum);

  if (!found)
      printf("No Gel data found for clone %s\n",clone->clone);
  return;
}

/********************************************************************
                 DEF: isthe cloneinthisgel
*******************************************************************/
static BOOL isthecloneinthisgel(int aceindex, int fpindex, char *altname, char *geldir, char *gelname)
{
  int i,kk;
  FILE *in;
  int lane, index;
  char buf[180], key[40], val[180];
  unsigned char *vp;
  CLONE *clone;
  int loop=-1,j,newposs=-1;

  if((in = fopen(messprintf("%s/%s", geldir,gelname),"r")) == NULL ){
    printf("Cannot open %s/%s\n",geldir,gelname);
    return FALSE;
  }
  clone = arrp(acedata,aceindex,CLONE);

  gelcloneindex[gelcount] = fpindex;
  gelclone[gelcount] = aceindex;
  buf[0] = '\0';
  while(strstr(buf, "Clones:") == NULL)
  {
      if ((fgets(buf, 80, in)) == NULL) {
         fprintf(stderr,
           "File %s/%s incorrect format, maybe empty.\n",geldir,gelname);
         return(FALSE);
      }
      sscanf(buf, "%s %s", key, val);
      if (strncmp(key, "BlockSize",9)==0)
             sscanf(buf, "%s %d", key, &blksz);
  }

  while(strstr(buf, "@@@") == NULL)
  {
      if ((fgets(buf, 80, in)) == NULL) {
         fprintf(stderr,"File %s/%s incorrect format\n",geldir, gelname);
         return(FALSE);
      }
      sscanf(buf, "%s %d %d", val, &lane, &index);
      if(strcmp(val,clone->clone)==0)
	loop = index;
      else if(altname[0]!='\0'){ /* could be fp-name if name change */
	if(strcmp(val,altname)==0)
	  loop = index;
      }
  }
  if (loop<0) {
    fclose(in);
    return(FALSE);
  }
  gelpixelptr = vp = (UCHAR *) messalloc (blksz);
  fread(vp, sizeof(unsigned char), 1, in);
  for(j=0;j<=loop;j++){
      if ((i=fread(vp, sizeof(unsigned char), blksz, in)) != blksz) {
	fprintf(stderr,"Error: cannot read gel file %s/%s with blksz %d\n",
                     geldir, gelname, blksz);
	fclose(in);
	return FALSE;
      }
  }
  fclose(in); 

  var_blksz[gelcount] =  blksz; 
  gelpixelsheight = MiN(ClipHeight, (blksz-Proj.MinClip)) / GelAvg;
  calcpixelptr[gelcount] = (UCHAR *) malloc (gelpixelsheight*gelpixelswidth); 

  calcpixels();
  messfree(gelpixelptr);
  gelcount++;

  if(gelhigh !=-1){
    for(kk=0;kk<GELMAX;kk++){
      if(gelclone[kk] == gelhigh){
	newposs = kk;
	break;
      }
    }
    if(newposs != -1) movegel(gelcount-1,newposs-1);
  }  
  return(1);
}
/***************************************************************
                  DEF: calcpixels
****************************************************************/
static void calcpixels()
{
  unsigned char forward[256], c, *x ,*y,*vp,*newp;
  int sum, j, i, k, l, fac ;

  fac = GelAvg;
  vp = gelpixelptr;
  newp = calcpixelptr[gelcount];
  /*graphRawMaps (forward, 0) ; */
  for (l = 0 ; l < 256 ; ++l)
        forward[l] = l;

  for (k=0, i = Proj.MinClip; k < gelpixelsheight && i<blksz; i+=GelAvg, k++)
    { sum = 0 ; x = &vp[i];
      fac = MiN((int)GelAvg, (blksz-i)+1);
      for (j = 0 ; j < fac ; ++j)
	sum += *x++ ;
      if ((int)(sum/fac)>=256) {
         printf("FPC error: extend limts of calcpixels %d\n",(int)(sum/fac));
         break;
      }
      c = forward[(int)(sum/fac)] ;
      y = &newp[gelpixelswidth*k] ;
      for (j = 0 ; j < gelpixelswidth ; j++)
	*y++ = c ;	   
    }
}

/***********************************************************
                DEF: turnoffall
***********************************************************/
static void turnoffall()
{
  if(geldelete){
    geldelete = FALSE;
    graphBoxDraw(geldeletebox,BLACK,WHITE);
  }
  if(geladd){
    geladd = FALSE;
    graphBoxDraw(geladdbox,BLACK,WHITE);
  }
  if(gelmove){
    gelmove = FALSE;
    graphBoxDraw(gelmovebox,BLACK,WHITE);
  }
  if(gelmove){
    gelmove = FALSE;
    graphBoxDraw(gelmovebox,BLACK,WHITE);
  }
  if(gelband){
    gelband = FALSE;
    graphBoxDraw(gelbandbox,BLACK,WHITE);
  }
  if(geltrail){
	geltrail = FALSE;
    graphBoxDraw(geltrailbox,BLACK,WHITE);
  }
}

/******************************************************************
                   DEF: gelorderandmove
*****************************************************************/
static void gelorderandmove()
{
  int i=0,j=0;
  unsigned char *tempcalcpixel[GELMAX];
  int tempgelclone[GELMAX],tempgelclonei[GELMAX],tempvar_blksz[GELMAX];
  int tempgel_trail[GELMAX];
  int *tempbands[GELMAX];
  struct contig *pctg;

  if (root==NULL) {
     gelredraw();
     return;
  }
  /* cari 10.5.4 doesn't seem to make any difference recalculorder();*/
  /* cari 10.5.4 is this causing the lose of merged contig? 
  if(ctg_window!=NULL)
    ctgdisplay(currentctg);
  */
  for(i=0;i<gelcount;i++)
    tempgelclone[i] = -1;
  
  for(pctg=root; pctg!=NULL; pctg=pctg->new){
    for(i=0;i<gelcount;i++){
      if(pctg->next == gelclone[i]){
	tempcalcpixel[j] = calcpixelptr[i];
	tempgelclone[j] = gelclone[i];
	tempgel_trail[j] = gel_trail[i];
	tempvar_blksz[j] = var_blksz[i];
	tempbands[j] = CloneBands[i];
	tempgelclonei[j++] = gelcloneindex[i];
        break;
      }
    }
  }
  for(i=0;i<j;i++){
    calcpixelptr[i] = tempcalcpixel[i];
    gelclone[i] = tempgelclone[i];
    gel_trail[i] = tempgel_trail[i];
    gelcloneindex[i] = tempgelclonei[i];
    var_blksz[i] =  tempvar_blksz[i];
    CloneBands[i] = tempbands[i];
  }
  for(;i<gelcount;i++){
    if (CloneBands[i]!=NULL) {
       free(CloneBands[i]);
       CloneBands[i] = NULL;
    }
    if (calcpixelptr[i]!=NULL) {
       /*free(calcpixelptr[i]);*/
       calcpixelptr[i]=NULL;
    }
    gelclone[i] = 0;
    gel_trail[i] = 0;
  }
  gelcount = j;
  gelredraw();
}
 
/****************************************************************
                  DEF: movegel
******************************************************************/
static void movegel(int startcol,int fincol)
{
  int i,j;
  unsigned char *tempcalcpixel[GELMAX];
  int tempgelclone[GELMAX],tempgelclonei[GELMAX],
      tempgelnamebox[GELMAX],tempvar_blksz[GELMAX]; 
  int tempgel_trail[GELMAX];
  int *tempbands[GELMAX];
  
  if(startcol == fincol) return;
  if(fincol < startcol) fincol = fincol +1;

  for(i=0;i<gelcount;i++){ 
      if(startcol < fincol){   
	if(i < startcol) j=i;
	else if(i == fincol) j=startcol;
	else if(i < fincol) j=i+1;
	else j=i;
      }
      else{                    /* else if moving a colomn backwards */
	if(i < fincol) j=i;
	else if(i == fincol) j=startcol;
	else if(i > fincol && i <= startcol) j=i-1;
	else j=i;
      }
      tempcalcpixel[i] = calcpixelptr[j];
      tempgelclone[i] = gelclone[j];
      tempgel_trail[i] = gel_trail[j];
      tempgelclonei[i] = gelcloneindex[j];
      tempgelnamebox[i] = gelnamebox[j];
      tempvar_blksz[i] = var_blksz[j]; 
      tempbands[i] = CloneBands[j]; 
  }

  for(i=0;i<gelcount;i++){ 
      calcpixelptr[i] = tempcalcpixel[i];
      gelclone[i] = tempgelclone[i];
      gel_trail[i] = tempgel_trail[i];
      gelnamebox[i] = tempgelnamebox[i];
      gelcloneindex[i] = tempgelclonei[i];
      var_blksz[i] = tempvar_blksz[i]; 
      CloneBands[i] = tempbands[i];
  }
}

/*****************************************************************
                  DEF: movegelscroll
******************************************************************/
static BOOL movegelscroll(float *x)
{
  int i;
  int col1,col2,fincol,numcol,startcol;
  float widthpercolomn;

  startcol = fincol = -2; 
  for(i=0;i<gelcount;i++){  
    if(MAP_BOX == gelclonebox[i]){
      startcol = i;
      break;
    }
  }
  numcol = gelcount; 

  widthpercolomn = 5.0;
  col1 = 5.0;
  if (*x <= col1) fincol = gelcolstart-1;
  for(i=0;i<numcol;i++){
    col2 = col1 + widthpercolomn;
    if(*x > col1 && *x <= col2){
      fincol = i+gelcolstart; 
      break;
    }
    col1 = col1 + widthpercolomn;
  }
  if(startcol < 0 || fincol < -1 || numcol < 0)
    return(FALSE);
  movegel(startcol,fincol);
  return(TRUE);
}

/*****************************************************************
                  DEF: gelmapdelete
******************************************************************/
static void gelmapdelete()
{
  int i,j;
  int startcol =-2;
  unsigned char *tempcalcpixel[GELMAX];
  int tempgelclone[GELMAX],tempgelclonei[GELMAX],
       tempgelnamebox[GELMAX],tempvar_blksz[GELMAX];
  int tempgel_trail[GELMAX];
  int *tempBands[GELMAX];

  for(i=0;i<gelcount;i++){
    if(MAP_BOX == gelclonebox[i]){
      startcol = i;
      break;
    }
  }
  if(startcol ==-2)
    return;
  for(i=j=0;i<gelcount;i++){ 
    if(i != startcol){     
      tempcalcpixel[j] = calcpixelptr[i];
      tempgelclone[j] = gelclone[i];
      tempgel_trail[j] = gel_trail[i];
      tempgelclonei[j] = gelcloneindex[i];
      tempgelnamebox[j] = gelnamebox[i];
      tempBands[j] = CloneBands[j];
      tempvar_blksz[j++] = var_blksz[i]; 
    }
    else {
      if (calcpixelptr[i]!=NULL) {
         /*free(calcpixelptr[i]); */
         calcpixelptr[i]=NULL;
      }
      if (CloneBands[i]!=NULL) {
          free(CloneBands[i]);
          CloneBands[i]=NULL;
      }
    }
  }
  gelcount--;
  for(i=0;i<gelcount;i++){ 
    calcpixelptr[i] = tempcalcpixel[i];
    gelclone[i] = tempgelclone[i];
    gel_trail[i] = tempgel_trail[i];
    gelcloneindex[i] = tempgelclonei[i];
    gelnamebox[i] = tempgelnamebox[i];
    var_blksz[i] = tempvar_blksz[i]; 
    CloneBands[i] = tempBands[i];
  }
  gelredraw();
}

/****************************************************************
               DEF: geldrag
****************************************************************/
static void geldrag(float *x, float *y, BOOL isUP)
{
  *y = YY;
  if(isUP)
    {
      if(movegelscroll(x))      /* if the scroll bar has been moved */
	gelredraw();        /* then redraw fp map */
    }
}
/****************************************************************
               DEF: gelscroll
****************************************************************/
static BOOL gelscroll(float *x)
{
  gelcolstart = (int)(*x/gelsizepercol);           /* set global shift to this */
  gelcolstart--; /* numbers in first lane */
  return(TRUE);
}
/****************************************************************
               DEF: gelscrolldrag
****************************************************************/
static void gelscrolldrag(float *x, float *y, BOOL isUP)
{
  *y = gelheight;
  if(isUP)
    {
      if(gelscroll(x))   /* if the scroll bar has been moved */
	gelredraw();        /* then redraw fp map */
    }
}

/**********************************************************
               DEF: IsItAnImage
********************************************************/
static BOOL IsItAnImage(int box)
{
  int i;

  for(i=0;i<gelcount;i++){
    if(gelclonebox[i] == box)
      return TRUE;
    else if(gelnamebox[i] == box)
      return FALSE;
  }
  return FALSE;
}
/**********************************************************
               DEF: gelpick
**********************************************************/
static void gelpick(int box, double x, double y)
{
  MAP_BOX = box;                /* store the box picked globally */

  if(box == gelscrollbar)
    graphBoxDrag(box, gelscrolldrag);
  else if(gelmove){
    if(IsItAnImage(box))
      graphBoxDrag(box, geldrag);
  }
  else if(box == greenbox) {
     greenflag = !greenflag;
     gelredraw();
  }
  else if(geldelete) gelmapdelete();
  else if(gelband) bandpick(box, x, y);
  else if(geltrail) trailgel(box,x,y);
  else gelclonehigh(box);
}
/**********************************************************
               DEF: bandpick
routine added by Ken McDonald. When band on gel image is picked,
the Calculator is displayed for it.
edited by CAS
********************************************************/
static Graph fragSizesWindow = 0;
static char lastCloneName[CLONE_SZ] = "";
static int inSum[NBANDS], fragSizes[NBANDS];
static int numOfFrags = 0;

static void bandpickQuit()
{
int i;
  if(graphActivate(fragSizesWindow))
    graphDestroy(); 
    for(i = 0; i < NBANDS; i++) fragSizes[i]=inSum[i] = 0;
    lastCloneName[0] = '\0';
     numOfFrags = 0;
}
static void bandpick(int box, double x, double y)
{
  int column;
  int i;
  CLONE *clone;
  FILE *bandsFilePtr;
  char bandsFileName0[1024];
  char bandsFileName1[1024];
  char bandsFileName2[1024];
  char bandsFileName3[1024];
  char line[100];
  char cloneNameFromFile[50];
  char tempString[50];
  int cloneFoundInFile = 0;
  int fgetsResult = 1;
  float fragWinYPos = 0.0;
  int fragWinNumEntries = 0;
  int bandIndex;
  int yInverse;

  int temp; /* used in reverseing the fragSizes[] array. */

  int sumOfSizes = 0;
  int totalFragSizes = 0;
  int nearestBand = 0;
  int nearestBandDiff = 10000;
  int migrationRate, blk = -1;
  float x1, y1, x2, y2;
  static MENUOPT sizemenu[] = {
    { bandpickQuit, "Close"},
    { graphPrint,"Print Screen"},
    { 0, 0 } };

  if(box==0 || !IsItAnImage(box)) return;

  for(column= -1, i=0;i<gelcount;i++){
     if(box == gelclonebox[i]) {
        blk = var_blksz[i];
        column = i;
	break;
      }
  }
  if (column==-1) return;

  graphBoxDim(box, &x1, &y1, &x2, &y2);
  clone = arrp(acedata, gelclone[column], CLONE);
  yInverse = (int)(y*GelUnit) - YY + Proj.MinClip;

  for (bandIndex = clone->fp->b1 - 1; 
        bandIndex <= clone->fp->b2 + clone->fp->b1 - 2; bandIndex++) {
      migrationRate = arr(bands, bandIndex, int);
      if (abs(migrationRate - yInverse) < nearestBandDiff) {
	nearestBandDiff = abs(migrationRate - yInverse);
	nearestBand = bandIndex - (clone->fp->b1 - 1);
      }
      else if (abs(migrationRate - yInverse) == nearestBandDiff) {
        if (yInverse > migrationRate)
	   nearestBand = bandIndex - (clone->fp->b1 - 1);
      }
   }
   inSum[nearestBand] = !inSum[nearestBand];
   cloneFoundInFile = 0;
   numOfFrags = clone->fp->b2;

   if (strcmp(clone->clone, lastCloneName)!=0) 
   {
      for(i = 0; i < NBANDS; i++) fragSizes[i]=inSum[i] = 0;
      strcpy(lastCloneName, clone->clone);

      sprintf(bandsFileName0, "%s/../../DONE/%s/%s.sizes", dirName, clone->fp->gelname, 
              clone->fp->gelname);
      sprintf(bandsFileName1, "%s/../DONE/%s/%s.sizes", dirName, 
            clone->fp->gelname, clone->fp->gelname);
      if (strlen(dirName) > 0) 
          sprintf(bandsFileName2, "%s/%s.sizes", dirName, clone->fp->gelname);
      else  sprintf(bandsFileName2, "%s.sizes",  clone->fp->gelname);
     
      if (strlen(dirName) > 0) 
        sprintf(bandsFileName3, "%s/Sizes/%s.sizes", dirName, clone->fp->gelname);
      else  sprintf(bandsFileName3, "Sizes/%s.sizes",  clone->fp->gelname);

      if (NULL != (bandsFilePtr = fopen(bandsFileName3, "r")) || 
	NULL != (bandsFilePtr = fopen(bandsFileName1, "r")) || 
	NULL != (bandsFilePtr = fopen(bandsFileName2, "r")) ||
	NULL != (bandsFilePtr = fopen(bandsFileName0, "r"))) 
      {
         while (!cloneFoundInFile && fgetsResult) 
         {
            fgetsResult = (int)fgets(line, 80, bandsFilePtr);
            sscanf(line, "%s", cloneNameFromFile);

            if (strcmp(cloneNameFromFile, clone->clone)==0 ||
                strcmp(cloneNameFromFile, clone->fp->fpchar)==0) {
	      cloneFoundInFile = 1;
	      numOfFrags = 0;
	      fscanf(bandsFilePtr, "%i", &temp);
              while (temp != -1) {
	         fragSizes[numOfFrags] = temp;
	         numOfFrags++;
	         fscanf(bandsFilePtr, "%i", &temp);
	      }

	          /* Reverse the fragSizes array. */
              for (i = 0; i < numOfFrags/2; i++) {
	         temp = fragSizes[i];
	         fragSizes[i] = fragSizes[numOfFrags - 1 - i];
	         fragSizes[numOfFrags - 1 - i] = temp;
	      }
            }
         }
         fclose(bandsFilePtr);
      }
  }
  else if (fragSizes[0]!=0) cloneFoundInFile = 1;

  if (graphExists(fragSizesWindow)) {
      graphActivate(fragSizesWindow);
      graphClear();
      graphPop();
  }
  else {
      if (cloneFoundInFile)
          fragSizesWindow = graphCreate(TEXT_SCROLL,"Fragment Sizes Window",0,0,0.25,0.5);
      else 
          fragSizesWindow = graphCreate(TEXT_SCROLL,"Migration Rate Window",0,0,0.25,0.5);
   }
   graphMenu(sizemenu);

   sumOfSizes = 0;
   totalFragSizes = 0;
   fragWinYPos = 0.5;

   sprintf(tempString, "Clone: %s (%d)", clone->clone, blk);
   graphText(tempString, 1.5, fragWinYPos);
   fragWinYPos += 1.5;
   fragWinNumEntries = 0;

   for (i=0; i < numOfFrags; i++) {
        if (cloneFoundInFile){
           sprintf(tempString,"%2d. %5d  %d",
                    i+1, arr(bands, clone->fp->b1+i-1, int), fragSizes[i]);
           totalFragSizes += fragSizes[i];
        }
        else {
           sprintf(tempString,"%2d. %5d", i+1, arr(bands, clone->fp->b1+i-1, int));
           totalFragSizes += arr(bands, clone->fp->b1+i-1, int);
        }
	  
        if (inSum[fragWinNumEntries]) {
           if (cloneFoundInFile) sumOfSizes += fragSizes[i];
           else sumOfSizes += arr(bands, clone->fp->b1+i-1, int);
           strcat(tempString, "+");
        }
        if (fragWinNumEntries == nearestBand) strcat(tempString, "<--");
        graphText(tempString, 1.0, fragWinYPos);
        fragWinYPos += 1.0;
	fragWinNumEntries++;
   }
   fragWinYPos += 0.5;
   sprintf(tempString, "Sum of '+': %d", sumOfSizes);
   graphText(tempString, 1.0, fragWinYPos);
   fragWinYPos += 1.0;
   sprintf(tempString, "TOTAL: %d", totalFragSizes);
   graphText(tempString, 1.0, fragWinYPos);
   graphTextBounds(20, fragWinNumEntries + 5);
   graphRedraw();
}

/*************************************************************
                DEF: togglegelmove
************************************************************/
static void togglegelmove()
{
BOOL save = gelmove;
  turnoffall();
  gelmove = !save;
  if(gelmove) graphBoxDraw(gelmovebox,BLACK,RED);
}

/*************************************************************
                DEF: togglegeladd
************************************************************/
static void togglegeladd()
{
BOOL save = geladd;
  turnoffall();
  geladd = !save;

  if(geladd) graphBoxDraw(geladdbox,BLACK,RED);

  if(fpflag){
    fpflag = FALSE;
    if(graphActivate(gselected))
      graphBoxDraw(fpflagbox,BLACK,WHITE);
  }
  if(fpadd){
    fpadd = FALSE;
    if(graphActivate(g3))
      graphBoxDraw(fpaddbox,BLACK,WHITE);
  }
}
/*************************************************************
                DEF: togglegelband
************************************************************/
static void togglegelband()
{
BOOL save = gelband;
  turnoffall();
  gelband = !save;
  if(gelband) graphBoxDraw(gelbandbox,BLACK,RED);
 
  if (graphExists(fragSizesWindow)) {
    graphActivate(fragSizesWindow);
    graphPop();
  }
}
/*************************************************************
                DEF: togglegeldelete
************************************************************/
static void togglegeldelete()
{
BOOL save = geldelete;
  turnoffall();
  geldelete = !save;
  if(geldelete) graphBoxDraw(geldeletebox,BLACK,RED);
}

/*************************************************************
                DEF: bandcolour
**************************************************************/
static BOOL bmatch(int kk, int b)
{
CLONE *clp;
struct fpdata *p=NULL;
int l, idiff, lstart, lend;

    if (kk< 0 || kk >= numposs || gelclone[kk]==-1) return FALSE;
    clp = arrp(acedata, gelclone[kk], CLONE);
    p = clp->fp;
    for(l=0;l<gelcloneindex[kk];l++) p = p->next;
    if(p == NULL) return FALSE;

    lstart = p->b1 - 1;
    lend =  p->b1 + p->b2 - 1 ;

    for(l=lstart;l<lend;l++){
        idiff=(b - arr(bands,l,int));
        if(Ztol(b, idiff)) return TRUE;
        else if (idiff < 0) return FALSE;
    }
return FALSE;
}

static int getcolour(int kk, int b)
{
int col=BLACK;
  if (gelhigh==-1) return BLACK;

  if (gelclone[kk] == gelhigh) {
      if (bmatch(kk-1, b) || bmatch(kk+1, b)) {
         if (!greenflag) col= BLUE;
         else col = GREEN;
      }
   }
  /* sness */
  else if (gel_trail[kk] == 1)
	col = MAGENTA;
  else if (kk>0 && gelclone[kk-1] == gelhigh) {
	if (bmatch(kk-1, b)) col= RED;
  }
  else if (kk<GELMAX && gelclone[kk+1] == gelhigh) {
	if (bmatch(kk+1, b)) col= RED;
  }
  if (col!=BLACK) graphColor(col);
return col;
}
/*************************************************************
                DEF: gelredraw
************************************************************/
void gelredraw()
{
  int  height, tmpcol, row, col;
  int c,i,kk,j,jj;
  char tmp[1024];
  float ytop=0,ybot=0,botscrollstart=0,botscrolllen=0,hblength=0,x=0;
  BOOL hozbar;
  int nx,ny;
  static MENUOPT gelmenu[] = {
  { gelquit, "Close"},
  { graphPrint,"Print Screen"},
  { 0, 0 } };

  CLONE *clone;
  struct fpdata *p=NULL;
  float y2,initx2, offset;
  int b, last = -1, xx;
  int colwid=5;

  if(graphActivate(gtest)){
    graphClear();
  }
  else{
    /*sness */
    /*graphGreyRamp(75, 0); */
    gexRampSet(75, 0);
    /* cari 7-5-4 remove opening greyramp here */
    /*gexRampTool();*/
    graphSetInstallMap(TRUE);
    gtest = graphCreate (TEXT_SCROLL, "Gel Image", 0, 0, 0.41, 1.0);
    graphRegister(PICK, gelpick) ;
    graphRegister(RESIZE,gelredraw);
    graphMenu(gelmenu);
    if (Proj.variable) {
      if (strlen(dirName)>0) sprintf(tmp, "%s/Sizes",dirName);
      else strcpy(tmp,"Sizes");
      if (filCheck(tmp,"d")) UseBandFiles=1;
      else UseBandFiles=0;
      for (i=0; i<GELMAX; i++) CloneBands[i]=NULL;
    }
  }
  row=1.0;
  /*sness */
  /*graphButton("GreyRamp",graphRampTool,1.0,row); */
  graphButton("GreyRamp",gexRampTool,1.0,row);
  graphButton("Whole",ZoomWhole,11.0,row);
  graphText("Zoom:",18.0,row);
  graphButton("In",ZoomIn,23.0,row);
  graphButton("Out",ZoomOut,27.0,row);
  sprintf(chgelavg,"%d", (int)GelAvg);
  gelavgbox = graphTextEntry(chgelavg, 2, 31.5, row,setgelzoom);
  geltrailbox = graphButton("Trail",toggletrail,35.0,row);

  row+=2.0;
  clipbox = graphButton("Clip",clipGel,1.0,row);
  sprintf(chclipmin,"%d", Proj.MinClip);
  clipminbox = graphTextEntry(chclipmin, 5, 7, row,setclipmin);
  sprintf(chclipmax,"%d", Proj.MaxClip);
  clipmaxbox = graphTextEntry(chclipmax, 5, 12, row,setclipmax);
  graphButton("Clear Trail",cleartrail,33.0,row);

  col = 20.0;
  greenbox = graphBoxStart();
  graphArc(col, 3.5, 0.7, 0, 360);
  if (greenflag) graphFillArc(col, 3.5, 0.4, 0, 360);
  graphBoxEnd();
  graphBoxDraw(greenbox, BLACK, TRANSPARENT);
  graphText("HighGreen",col+1,3.0);

  row+=2.0;
  gelmovebox = graphButton("Move",togglegelmove,1.0,row);
  geldeletebox = graphButton("Remove",togglegeldelete,7.0,row);
  geladdbox = graphButton("Add",togglegeladd,15.0,row);
  gelbandbox = graphButton("Band",togglegelband,20.0,row);
  graphButton("Redraw",gelorderandmove,26.0,row);
  graphButton("Remove All",gelremoveall,34.0,row);

  YY = row + 2.0 + 4.0;

  if(gelmove) graphBoxDraw(gelmovebox,BLACK,RED);
  else graphBoxDraw(gelmovebox,BLACK,WHITE);
  if(geladd) graphBoxDraw(geladdbox,BLACK,RED);
  else graphBoxDraw(geladdbox,BLACK,WHITE);
  if(geldelete) graphBoxDraw(geldeletebox,BLACK,RED);
  else graphBoxDraw(geldeletebox,BLACK,WHITE);
  if(gelband) graphBoxDraw(gelbandbox,BLACK,RED);
  else graphBoxDraw(gelbandbox,BLACK,WHITE);
  if(geltrail) graphBoxDraw(geltrailbox,BLACK,RED);
  else graphBoxDraw(geltrailbox,BLACK,WHITE);

  graphFitBounds(&nx,&ny);

  offset = colwid+0.5;
  if((gelcount*(float)offset)+(float)colwid > nx) hozbar = TRUE;
  else hozbar = FALSE;

  numposs = (int)((nx-colwid)/offset);
  if(hozbar){
    if(gelcolstart<0) gelcolstart = 0;
    else if(gelcolstart+numposs > gelcount)
      gelcolstart = gelcount - numposs;
  }
  else{
    gelcolstart=0;
    numposs = gelcount;
  }

  for(i=0;i<gelcount;i++){
    gelclonebox[i] = -1;
    gelnamebox[i] = 0;
  }
  j=0;
  for(c=0,kk=gelcolstart;kk<gelcolstart+numposs;kk++){
    j++;
    gelnamebox[kk] = graphBoxStart();
    if(c==0) {
      graphText(arrp(acedata,gelclone[kk],CLONE)->clone,((5*j)),YY-2.0);
      c++;
    }
    else if(c==1) {
      graphText(arrp(acedata,gelclone[kk],CLONE)->clone,((5*j)),YY-3.0);
      c++;
    }
    else {
      graphText(arrp(acedata,gelclone[kk],CLONE)->clone,((5*j)),YY-4.0);
      c=0;
    }
    graphBoxEnd();

    if (gel_trail[kk] == 1) {
        graphBoxDraw(gelnamebox[kk],MAGENTA,WHITE);
    }

    if(gelhigh != -1){
      if(gelclone[kk] == gelhigh)
	graphBoxDraw(gelnamebox[kk],BLUE,WHITE);
    }

    gelclonebox[kk] = graphBoxStart();
    
    clone = arrp(acedata, gelclone[kk], CLONE);
    initx2 = (float)j * 5.0;

    if(clone->fp == NULL) continue;

    p = clone->fp;
    for (i=0;i<gelcloneindex[kk];i++) p = p->next;

    if (UseBandFiles) {
       if (CloneBands[kk]==NULL) 
           if (!GetBands(clone, kk, p)) continue;
       for(jj=0; CloneBands[kk][jj]!=-1;jj++){
          b =  CloneBands[kk][j];
          if (b < Proj.MinClip || b > Proj.MaxClip) continue;
          tmpcol = getcolour(kk, b);
          y2 = YY + ((float) (b-Proj.MinClip) / GelUnit);
          if (last==b) y2+=0.1; /* use instead of linewidth for bandpick */
          graphLine(initx2+1.0,y2,initx2+2.0,y2);
          graphLine(initx2+4.5,y2,initx2+5.5,y2);
          if (tmpcol!=BLACK) graphColor(BLACK);
          last = b;
       }
     }
     else {
       last = -1;
       for(jj=-1;jj<p->b2-1;jj++){
           b =  arr(bands,p->b1+jj,int);
           if (b < Proj.MinClip || b > Proj.MaxClip) continue;
           tmpcol = getcolour(kk, b);
           y2 = YY + ((float) (b-Proj.MinClip) / GelUnit);
           if (last==b) y2+=0.1; /* use instead of linewidth for bandpick */
           graphLine(initx2+1.0,y2,initx2+2.0,y2);
           graphLine(initx2+4.5,y2,initx2+5.5,y2);
           if (tmpcol!=BLACK) graphColor(BLACK);
           last = b;
       }
     }
     height = MiN(ClipHeight, (var_blksz[kk]-Proj.MinClip)) / GelAvg;
     graphPixelsRaw((unsigned char *)calcpixelptr[kk],gelpixelswidth,
		   height,gelpixelswidth,((float)j*5.0)+2.25,YY);
     graphBoxEnd();
  }
  
  if (GelAvg <=2.0) xx=25;
  else if (GelAvg <=3.0) xx=50;
  else xx = 100;
  graphText("Rate",1.0,YY-2.5);
  for (kk=Proj.MinClip; kk<Proj.MaxClip+xx; kk+=xx) {
      sprintf(tmp,"%d",kk);
      graphText(tmp,1.0,YY+(((float)(kk-Proj.MinClip)/GelUnit)-0.75));
  }

  ytop = YY + (int) (ClipHeight/GelUnit) + 3; 
  if(hozbar){ /* draw the background for the bar */
    gelheight = ytop;
    ybot = ytop +1;
    hblength = numposs*colwid;
    gelsizepercol = (float) hblength/(float)gelcount;
    for(i=0;i<gelcount;i++){
      x = 5.0+((float)i*gelsizepercol);
      graphRectangle(x,ytop,x+gelsizepercol,ybot);
    }
           /* draw the scroll bar */
    botscrollstart = (gelcolstart*gelsizepercol)+colwid;
    botscrolllen = ((float)numposs/(float)gelcount)*hblength;
    gelscrollbar = graphBoxStart();
    graphRectangle(botscrollstart,ytop,botscrollstart+botscrolllen,ybot);
    graphBoxEnd();
    graphBoxDraw(gelscrollbar,BLACK,GREEN);
  }
  else gelscrollbar = -1;

  gelavgbox = graphTextEntry(chgelavg, 2, 31.5, row,setgelzoom);
  graphTextBounds(6, ytop+2);
  graphRedraw();
}

/* sness Sep21/2000 */
/* */
/******************************************************************
                   DEF: toggletrail
Toggle the trail mode on and off

When FPC is in Trail mode, all clones picked on the gel window
are turned magenta and stay this colour until their color is cleared
with the "Clear Trail" button.  This is a useful "bookmarking" 
function when moving large numbers of gels around
*****************************************************************/
static void toggletrail()
{
  BOOL save = geltrail;

  turnoffall();
  geltrail = !save;

  if(geltrail) {
	graphBoxDraw(geltrailbox,BLACK,RED);
  }
  gelredraw();
  graphPop();
}
/* sness Sep21/2000 */
/* */
/******************************************************************
                   DEF: cleartrail
Clears all the currently Trailed clones
*****************************************************************/
static void cleartrail()
{
  int i;

  turnoffall();

  for(i=0;i<gelcount; i++)
	gel_trail[i] = 0;

  gelredraw();
  graphPop();
}

/* sness Sep21/2000 */
/* */
/******************************************************************
                   DEF: trailgel
 From the box number fed in, determine which gel was picked
and turn on the corresponding element in gel_trail, so that it
will be highlighted.
*****************************************************************/
static void trailgel(int box, double x, double y)
{
  int i;
  int column, blk;
  
  if(box==0 || !IsItAnImage(box)) return;

  for(column= -1, i=0;i<gelcount;i++){
     if(box == gelclonebox[i]) {
        blk = var_blksz[i];
        column = i;
	break;
      }
  }
  if (column==-1) return;

  gel_trail[column] = 1;
  gelredraw();
  graphPop();
}
/* sness Jul6/2000 */
/******************************************************************
                   DEF: gelremoveall
Remove all gels from the gel window
*****************************************************************/
static void gelremoveall()
{
  int i;

  printf("Removing all clones from gelimage\n");

  for(i=0;i<gelcount; i++){
    gelclone[i] = 0;
	gel_trail[i] = 0;
    if (calcpixelptr[i]!=NULL) {
       /*free(calcpixelptr[i]);*/
       calcpixelptr[i]=NULL;
    }
    if (CloneBands[i]!=NULL) {
       free(CloneBands[i]);
       CloneBands[i]=NULL;
    }
  }
  gelcount = 0;
  gelhigh = -1;
  gelredraw();
}
